﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security;

namespace Idlesoft.Utils
{
	public static class StringExtensions
	{
		public static string Format(this string format, params object[] args)
		{
			return string.Format(format, args);
		}
		public static string[] Separate(this string text, string anchor, bool before = true)
		{
			var selector = before ? new Func<string, string>(s => anchor + s) : new Func<string, string>(s => s + anchor);
			return text.Split(new string[] { anchor }, StringSplitOptions.RemoveEmptyEntries).Select(selector).ToArray();
		}

		#region chars and strings

		public static string WithArgs(this string text, params object[] args)
		{
			return string.Format(text, args);
		}

		public static SecureString ToSecureString(this string text)
		{
			var secure = new SecureString();
			text.ToCharArray().ForEach(c => secure.AppendChar(c));
			return secure;
		}

		public static string Reverse(this string text)
		{
			return text.Reverse<char>().AsString();
		}

		public static string[] SplitWords(this string text)
		{
			var words = text.ToCharArray().Fold(
				(acc, c) =>
				{
					if (Char.IsUpper(c))
						acc.Add(new List<char> { c });
					else
						acc.Last().Add(c);
					return acc;
				}, new List<List<char>>());

			return words.Select(w => w.ToString()).ToArray();
		}

		public static string AsString(this IEnumerable<char> chars)
		{
			return new string(chars.ToArray());
		}
		public static string Uppers(this string text)
		{
			var uppers = Uppers(text.ToCharArray()).AsString();
			return uppers;
		}
		public static string Lowers(this string text)
		{
			return Lowers(text.ToCharArray()).ToString();
		}

		public static char[] Uppers(this char[] chars)
		{
			var uppers = chars.Where(c => Char.IsUpper(c)).ToArray();
			return uppers;
		}
		public static char[] Lowers(this char[] chars)
		{
			return chars.Where(c => Char.IsLower(c)).ToArray();
		}

		public static int[] UpperIndices(this string text)
		{
			int index = -1;
			return text.ToCharArray().Select(
				c =>
				{
					++index;
					return Char.IsUpper(c) ? index : -1;
				}).Where(i => i >= 0).ToArray();
		}
		public static int[] LowerIndices(this string text)
		{
			int index = -1;
			return text.ToCharArray().Select(
				c =>
				{
					++index;
					return Char.IsLower(c) ? index : -1;
				}).Where(i => i >= 0).ToArray();
		}

		public static string Trim(this string text)
		{
			int count = text.Reverse().Count(c => Char.IsWhiteSpace(c));
			return text.Trim(count);
		}
		public static string Trim(this string text, int num)
		{
			return text.Substring(0, text.Length - num);
		}
		#endregion chars and strings
	}
}
